package cn.ac.big.bigd.util;


import cn.ac.big.bigd.exception.AccessionOverFlowException;

public class AccessionUtil {
        
    public static String prjAccession = "PRJCA000000";
	public static String sampleAccession = "SAMC000000";
	public static String exptAccession = "CRX000000";
	public static String runAccession = "CRR000000";
	
	/*Added by wangyanqing on 2016-12-15*/
	public static String craAccession = "CRA000400";
	public static String crpAccession = "CRP000400";
	public static String crsAccession = "CRS010000";


	public static String wgsAccession = "WGS000000";

	public static String accession = "GWHAAAA00000000";


	public static String blastAccession = "000000000000";


	/**
	 * 字母自增
	 * @param str
	 * @return
	 */
	private static String letterAdd(String str) {
		int len = str.length();
		int startI = len - 1;
		String tempA = "";
		String tempB = "";
		while (true) {
			tempA = "";
			if (startI > 0) {
				tempA = str.substring(0, startI);
			}
			if (startI < 0 && len == 0) {
				tempA = str;
				tempB = "A";
				break;
			} else {
				tempB = str.substring(startI, len);
				byte[] gc = tempB.getBytes();
				int lastCode = (int) gc[0];
				lastCode++;
				if (lastCode <= 90) {
					char a = (char)lastCode;
					tempB = a+"";
					break;
				}
				startI--;
				len--;
			}
		}


		String newStr = tempA + tempB;
		while (newStr.length() < str.length()) {
			newStr += "A";
		}
		return newStr;
	}

	/**
	 * 字母自减
	 * @param str
	 * @return
	 */
	private static String letterMinus(String str) {
		int len = str.length();
		int startI = len - 1;
		String tempA = "";
		String tempB = "";
		while (true) {
			tempA = "";
			if (startI > 0) {
				tempA = str.substring(0, startI);
			}
			if (startI < 0 && len == 0) {
				tempA = str;
				tempB = "A";
				break;
			} else {
				tempB = str.substring(startI, len);
				byte[] gc = tempB.getBytes();
				int lastCode = (int) gc[0];
				lastCode--;
				if (lastCode >= 65) {
					char a = (char)lastCode;
					tempB = a+"";
					break;
				}
				startI--;
				len--;
			}
		}


		String newStr = tempA + tempB;
		while (newStr.length() < str.length()) {
			newStr += "Z";
		}
		return newStr;
	}


	public static void main(String[] args) {

		try {
			addBlast();
		} catch (AccessionOverFlowException e) {
			e.printStackTrace();
		}
	}


	/**
	 *
	 * Accession + 1
	 * @throws AccessionOverFlowException
	 * void
	 */
//	public synchronized static void addAcc() throws AccessionOverFlowException {
//		String prefix ="gwh";
//		String minusStr = accession.substring(3, 7);
//		System.out.println(minusStr);
//		String numCode = accession.substring(7);
//		System.out.println(numCode);
//		String  result = letterMinus(minusStr);
//		String newAccession = prefix + result+ numCode;
//		accession = newAccession;
//		System.out.println("ACCESSION:"+AccessionUtil.accession);
//	}


	public synchronized static void addAcc() throws AccessionOverFlowException {
		String prefix ="GWH";
		String minusStr = accession.substring(3, 7);
		String numCode = accession.substring(7);
		String  result = letterAdd(minusStr);
		String newAccession = prefix + result+ numCode;
		accession = newAccession;
		System.out.println("ACCESSION:"+AccessionUtil.accession);
	}
	public synchronized static void addBlast() throws AccessionOverFlowException {

		String numCode = blastAccession;
		long num= Long.parseLong(numCode) + 1;
		if (num == 1000000000000L) {

			throw new AccessionOverFlowException("Accession overflow");


		} else {
			numCode = numCode.substring(0, 12 - String.valueOf(num).length())
					+ num;
		}
		String newAccession =  numCode;
		blastAccession = newAccession;
		System.out.println("ACCESSION:"+AccessionUtil.blastAccession);
	}
	/**
	 * WGS
	 * Accession + 1
	 * @throws AccessionOverFlowException
	 * void
	 */
	public synchronized static void addWGSAcc() throws AccessionOverFlowException {
		String prefix = wgsAccession.substring(0, 3);
		String numCode = wgsAccession.substring(3);
		int num = Integer.parseInt(numCode) + 1;
		if (num == 1000000) {
			throw new AccessionOverFlowException("Accession overflow");

		} else {
			numCode = numCode.substring(0, 6 - String.valueOf(num).length())
					+ num;
		}
		//String newAccession = prefix + alphaCode + numCode;
		String newAccession = prefix +  numCode;
		wgsAccession = newAccession;
		System.out.println("WGS:"+AccessionUtil.wgsAccession);
	}


	/**
	 * prjAccession + 1
	 * @throws AccessionOverFlowException
	 * void
	 */
	public synchronized static void addPrjAcc() throws AccessionOverFlowException {
		String prefix = prjAccession.substring(0, 4);
		char alphaCode = prjAccession.charAt(4);
		String numCode = prjAccession.substring(5);
		int num = Integer.parseInt(numCode) + 1;
		if (num == 1000000) {
			if (alphaCode == 'Z') {
				throw new AccessionOverFlowException("Accession overflow");
			} else {
				alphaCode += 1;
				numCode = "000000";
			}

		} else {
			numCode = numCode.substring(0, 6 - String.valueOf(num).length())
					+ num;
		}
		String newAccession = prefix + alphaCode + numCode;
		prjAccession = newAccession;
		System.out.println("acc:"+AccessionUtil.prjAccession);
	}
	
	/**
	 * sampleAccession + 1
	 * @throws AccessionOverFlowException
	 * void
	 */
	public synchronized static void addSampleAcc() throws AccessionOverFlowException{
		String prefix = sampleAccession.substring(0, 4);
		//char alphaCode = sampleAccession.charAt(4);
		String numCode = sampleAccession.substring(4);
		int num = Integer.parseInt(numCode) + 1;
		if (num == 1000000) {
			//if (alphaCode == 'Z') {
				throw new AccessionOverFlowException("Accession overflow");
			//} else {
				//alphaCode += 1;
				//numCode = "000000";
			//}

		} else {
			numCode = numCode.substring(0, 6 - String.valueOf(num).length())
					+ num;
		}
		//String newAccession = prefix + alphaCode + numCode;
		String newAccession = prefix + numCode;
		sampleAccession = newAccession;
	}
	
	/**
	 * exptAccession + 1
	 * @throws AccessionOverFlowException
	 * void
	 */
	public synchronized static void addExptAcc() throws AccessionOverFlowException{
		String prefix = exptAccession.substring(0, 3);
		//char alphaCode = exptAccession.charAt(3);
		String numCode = exptAccession.substring(3);
		int num = Integer.parseInt(numCode) + 1;
		if (num == 1000000) {
			//if (alphaCode == 'Z') {
				throw new AccessionOverFlowException("Accession overflow");
			//} else {
				//alphaCode += 1;
				//numCode = "000000";
			//}

		} else {
			numCode = numCode.substring(0, 6 - String.valueOf(num).length())
					+ num;
		}
		//String newAccession = prefix + alphaCode + numCode;
		String newAccession = prefix  + numCode;
		
		exptAccession = newAccession;
	}
	
	/**
	 * runAccession + 1
	 * @throws AccessionOverFlowException
	 * void
	 */
	public synchronized static void addRunAcc() throws AccessionOverFlowException{
		String prefix = runAccession.substring(0, 3);
		//char alphaCode = runAccession.charAt(3);
		String numCode = runAccession.substring(3);
		int num = Integer.parseInt(numCode) + 1;
		if (num == 1000000) {
			//if (alphaCode == 'Z') {
				throw new AccessionOverFlowException("Accession overflow");
			//} else {
				//alphaCode += 1;
				//numCode = "000000";
			//}

		} else {
			numCode = numCode.substring(0, 6 - String.valueOf(num).length())
					+ num;
		}
		//String newAccession = prefix + alphaCode + numCode;
		String newAccession = prefix +  numCode;
		runAccession = newAccession;
	}  
	
	/**
	 * craAccession + 1
	 * @throws AccessionOverFlowException
	 * void
	 */
	public synchronized static void addCraAcc() throws AccessionOverFlowException{
		String prefix = craAccession.substring(0, 3);
		//char alphaCode = runAccession.charAt(3);
		String numCode = craAccession.substring(3);
		int num = Integer.parseInt(numCode) + 1;
		if (num == 1000000) {
			//if (alphaCode == 'Z') {
				throw new AccessionOverFlowException("Accession overflow");
			//} else {
				//alphaCode += 1;
				//numCode = "000000";
			//}

		} else {
			numCode = numCode.substring(0, 6 - String.valueOf(num).length())
					+ num;
		}
		//String newAccession = prefix + alphaCode + numCode;
		String newAccession = prefix +  numCode;
		craAccession = newAccession;
	} 
	
	/**
	 * crpAccession + 1
	 * @throws AccessionOverFlowException
	 * void
	 */
	public synchronized static void addCrpAcc() throws AccessionOverFlowException{
		String prefix = crpAccession.substring(0, 3);
		//char alphaCode = runAccession.charAt(3);
		String numCode = crpAccession.substring(3);
		int num = Integer.parseInt(numCode) + 1;
		if (num == 1000000) {
			//if (alphaCode == 'Z') {
				throw new AccessionOverFlowException("Accession overflow");
			//} else {
				//alphaCode += 1;
				//numCode = "000000";
			//}

		} else {
			numCode = numCode.substring(0, 6 - String.valueOf(num).length())
					+ num;
		}
		//String newAccession = prefix + alphaCode + numCode;
		String newAccession = prefix +  numCode;
		crpAccession = newAccession;
	}
	
	/**
	 * crsAccession + 1
	 * @throws AccessionOverFlowException
	 * void
	 */
	public synchronized static void addCrsAcc() throws AccessionOverFlowException{
		String prefix = crsAccession.substring(0, 3);
		//char alphaCode = runAccession.charAt(3);
		String numCode = crsAccession.substring(3);
		int num = Integer.parseInt(numCode) + 1;
		if (num == 1000000) {
			//if (alphaCode == 'Z') {
				throw new AccessionOverFlowException("Accession overflow");
			//} else {
				//alphaCode += 1;
				//numCode = "000000";
			//}

		} else {
			numCode = numCode.substring(0, 6 - String.valueOf(num).length())
					+ num;
		}
		//String newAccession = prefix + alphaCode + numCode;
		String newAccession = prefix +  numCode;
		crsAccession = newAccession;
	}
}